import functools
import traceback
from functools import wraps

import jwt
from config.const import Const
from flask import g, jsonify, make_response, request
from log import logger


def handle(func):
    """
    error handle
    :param func: func without callable
    :return: func with callable
    """
    @wraps(func)
    def wrapper(*args, **kwargs):
        try:
            res = func(*args, **kwargs)
        except Exception as e:
            logger.info(traceback.format_exc())
            return jsonify({'msg': '意外的原因, 报错为: {e}'.format(e=str(e))}), 400
        return res

    return wrapper


def authorized(func):
    """
    auth decorator
    :param func: func
    :return: func(*args, **kwargs)
    """
    @wraps(func)
    def wrapper(*args, **kwargs):
        if request.headers.get('Authorization'):
            jwt_token = request.headers.get('Authorization').split()[-1]
        else:
            return make_response(jsonify({'msg': 'unathorized, please make sure your jwt token is right'}), 401)
        try:
            g.token = jwt.decode(jwt_token, Const.JWT_SECRET, algorithms='HS256')
        except Exception as e:
            logger.exception(e)
            return make_response(jsonify({'msg': 'unathorized, please make sure your jwt token is right'}), 401)
        return func(*args, **kwargs)

    return wrapper


def with_application(func):
    """flask上下文装饰器"""
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        application = flask_env()
        with application.app_context():
            return func(*args, **kwargs)

    return wrapper


def flask_env(config_name='prod'):
    """专门给with_application使用的flask环境 去除了蓝图, 只有db环境"""

    from flask import Flask
    from config.config import config
    from flask_sqlalchemy import SQLAlchemy
    app = Flask(__name__)
    app.config.from_object(config[config_name])
    SQLAlchemy(app)
    return app
